package com.finance.system.controller;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.finance.base.enums.OpearteEnum;
import com.finance.base.enums.StateEnum;
import com.finance.base.enums.TargetEnum;
import com.finance.framework.controller.Result;
import com.finance.framework.lang.BeanUtils;
import com.finance.framework.lang.Page;
import com.finance.framework.lang.PageResultBO;
import com.finance.base.constant.BaseConstants;
import com.finance.framework.controller.BaseController;
import com.finance.base.exception.BaseException;
import com.finance.rule.service.ISettingLogService;
import com.finance.system.bean.pojo.Menu;
import com.finance.system.bean.pojo.Role;
import com.finance.system.bean.pojo.RoleList;
import com.finance.system.bean.pojo.User;
import com.finance.system.request.RoleListReq;
import com.finance.system.request.RoleReq;
import com.finance.system.request.UserRoleReq;
import com.finance.system.service.IMenuService;
import com.finance.system.service.IRoleService;
import com.finance.system.service.IUserService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

/**
 * Created by CBWL on 2017/3/21.
 */
@Controller
@RequestMapping("/system/role")
public class RoleController extends BaseController {
    private static Logger logger = LoggerFactory.getLogger(RoleController.class);

    @Resource
    private IRoleService roleService;

    @Resource
    private IUserService userService;

    @Resource
    private IMenuService menuService;

    @Resource
    private ISettingLogService settingLogService;

    private ObjectMapper objectMapper=  new ObjectMapper();


    /**
     * 角色管理
     * @return
     */
    @RequestMapping("/index.htm")
    public String index(){
        return "system/role/index";
    }

    /**
     * 角色详情页
     * @param id
     * @param request
     * @return
     */
    @RequestMapping(value = "/update.htm",method = RequestMethod.GET)
    public String update(String id, HttpServletRequest request){
        Role role = this.roleService.getByRoleId(Long.parseLong(id));
        request.setAttribute("role",role);
        return "system/role/update";
    }

    /**
     * 查询角色信息
     * @param roleListReq
     * @return
     */
    @RequestMapping("/list")
    public Result list(RoleListReq roleListReq){
        Page page = Page.getInstance(roleListReq);
        RoleList roleList = new RoleList();
        PageResultBO<Role> resultBO;
        try {
            BeanUtils.copyProperties(roleList,roleListReq);
            page.setParams(roleList);
            resultBO = this.roleService.listByPage(page);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"系统异常");
        }
        return getSuccessResult(resultBO);
    }

    /**
     * 新增角色
     * @param roleReq
     * @return
     * @throws BaseException
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public Result add(@Valid RoleReq roleReq,String menuCodes) throws BaseException{
        User authUser = getAuthUser();
        if(roleReq == null || StringUtils.isBlank(roleReq.getName())){
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        if(authUser == null){
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        Role role = new Role();
        List<String> menuCodeList = Arrays.asList(menuCodes.split(","));
        try {
            BeanUtils.copyProperties(role,roleReq);
            role.setState(StateEnum.Valid.getState());
            this.roleService.add(role,menuCodeList);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"新增角色失败");
        }
        role.setCreateUid(authUser.getId());
        return getSuccessResult("新增角色成功");
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete",method = RequestMethod.POST )
    public Result delete(String id) throws BaseException{
        if (StringUtils.isBlank(id)){
            return getFailResult(BaseConstants.ERR_INVALID_PARAMETER,"参数缺失");
        }
        try {
            this.roleService.delete(id);
        } catch (BaseException e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"删除失败");
        }
        return getSuccessResult("删除角色成功");
    }

    /**
     * 更新角色
     * @param roleReq
     * @return
     * @throws BaseException
     */
    @RequestMapping(value = "/update",method = RequestMethod.POST)
    public Result update(@Valid RoleReq roleReq,String menuCodes) throws BaseException {
        Role oldRole = roleService.getById(roleReq.getId());
        if (oldRole == null){
            throw new BaseException(BaseConstants.ERR_NON_EXISTENT);
        }
        User authUser = getAuthUser();
        Role role = new Role();
        List<String> menuCodesList = Arrays.asList(menuCodes.split(","));
        try {
            BeanUtils.copyProperties(role,roleReq);
            role.setState(StateEnum.Valid.getState());
            this.roleService.update(role,menuCodesList);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"更新失败");
        }
        role.setUpdateUid(authUser.getId());

        List<String> menuCodeList=new ArrayList<String>();
        if(CollectionUtils.isNotEmpty(oldRole.getMenuList())){
            for (Menu menu:oldRole.getMenuList()){
                menuCodeList.add(menu.getCode());
            }
        }

        oldRole.setMenuList(null);
        oldRole.setMenuCodeList(menuCodeList);
        String oldValue=null;
        try {
            oldValue=objectMapper.writeValueAsString(oldRole);
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(),e);
        }
        settingLogService.addLog(authUser, OpearteEnum.UPDATE, TargetEnum.ROLE_PERMISSION_INFO,oldValue);

        return getSuccessResult("更新角色成功");
    }

    /**
     * 新增授权角色
     * @param userRoleReq
     * @return
     * @throws BaseException
     */
    @RequestMapping(value = "/add4user",method = RequestMethod.POST)
    public Result add4User(@Valid UserRoleReq userRoleReq) throws BaseException{
        User user = this.userService.getById(Long.parseLong(userRoleReq.getUserId()));
        Role role = this.roleService.getById(userRoleReq.getRoleId());
        if(user == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        if(role == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_ROLE);
        }
        try {
            this.roleService.add4User(user,getAuthUser(),role);
        }catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"授权失败");
        }
        return this.getSuccessResult("授权成功");
    }

    /**
     * 授权角色更新
     * @param userRoleReq
     * @return
     * @throws BaseException
     */
    @RequestMapping(value = "/modify4user",method = RequestMethod.POST)
    public Result modify4user(@Valid  UserRoleReq userRoleReq) throws BaseException {
        User user = this.userService.getById(Long.parseLong(userRoleReq.getUserId()));
        Role role = this.roleService.getById(userRoleReq.getRoleId());
        if (user == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_USER);
        }
        if (role == null) {
            throw new BaseException(BaseConstants.ERR_UNKONW_ROLE);
        }
        try {
            this.roleService.modify4user(user, getAuthUser(), role);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            logger.error(e.getMessage());
            return getFailResult(BaseConstants.ERR_UNKOWN,"角色授权更新失败");
        }
        return this.getSuccessResult("角色授权更新成功");
    }

    /**
     * 批量删除角色
     * @param ids
     * @return
     */
    @RequestMapping("/batchdel")
    public Result batchDel(String ids)throws BaseException{
        if (StringUtils.isBlank(ids)){
            return getFailResult(BaseConstants.ERR_INVALID_PARAMETER,"参数缺失");
        }
        List<String> list = Arrays.asList(ids.split(","));
        if(list.size()>0){
            try {
                this.roleService.batchDelRole(list);
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
                logger.error(e.getMessage());
                return getFailResult(BaseConstants.ERR_UNKOWN,"删除角色信息失败");
            }
        }
        return getSuccessResult("删除角色信息成功");
    }

    /**
     * 获取角色树
     * @return
     */
    @RequestMapping("/listmenu")
    public Result listMenu(){
        List<Menu> menus = new ArrayList<Menu>();
        menus.addAll(this.menuService.listAll());
        return getSuccessResult(menus);
    }

    /**
     * 获取已选中的菜单树
     * @return
     */
    @RequestMapping(value = "/checkedmenu" ,method = RequestMethod.GET)
    public Result getMenuChecked(String roleId){
        if(StringUtils.isBlank(roleId)){
            throw new BaseException(BaseConstants.ERR_INVALID_PARAMETER);
        }
        List<Menu> menuList = menuService.getByRoleId(Long.parseLong(roleId));
        List<Menu> menus = this.menuService.listAll();
        if(menuList != null && menuList.size() >0){
            for(Menu menu : menus){
                for(Menu menuChecked : menuList){
                    if(menu.getCode().equals(menuChecked.getCode())){
                        menu.setChecked(true);
                    }
                }
            }
        }
        return getSuccessResult(menus);
    }
}
